import JsEncrypt from './jsencrypt.min.js'

import * as types from './types'
import { PUBLIC_KEY } from '../config.js'

/**
 * guid
 */
export function guid() {
	function S4() {
		return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
	}
	return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4())
}

/**
 * 对象深拷贝
 * @author yxk
 */
export function deepCopy(target = null) {
	let res = null
	if (typeof target === 'object') {
		if (types.isArray(target)) {
			res = []
			target.forEach(item => {
				res.push(deepCopy(item))
			})
		} else if (types.isObject(target)) {
			res = {}
			const keys = Object.keys(target)
			keys.forEach(key => {
				res[key] = deepCopy(target[key])
			})
		} else {
			res = target
		}
	} else {
		res = target
	}
	return res
}

/**
 * 两个浮点数求和
 * @author yxk
 * @param num1
 * @param num2
 * @return {number}
 */
export function addOperation(num1, num2) {
	let r1, r2, m;
	try {
		r1 = (num1.toString().split('.')[1] || []).length;
	} catch (e) {
		r1 = 0;
	}
	try {
		r2 = (num2.toString().split('.')[1] || []).length;
	} catch (e) {
		r2 = 0;
	}
	m = Math.pow(10, Math.max(r1, r2));
	return Math.round(multiOperation(num1, m) + multiOperation(num2, m)) / m;
}

/**
 * 两个浮点数相减
 * @author yxk
 * @param num1
 * @param num2
 * @return {number}
 */
export function subOperation(num1, num2) {
	let r1, r2, m;
	try {
		r1 = (num1.toString().split('.')[1] || []).length;
	} catch (e) {
		r1 = 0;
	}
	try {
		r2 = num2.toString().split('.')[1].length;
	} catch (e) {
		r2 = 0;
	}
	m = Math.pow(10, Math.max(r1, r2));
	return Math.round(multiOperation(num1, m) - multiOperation(num2, m)) / m;
}

/**
 * 两个浮点数相乘
 * @author yxk
 * @param num1
 * @param num2
 * @return {number}
 */
export function multiOperation(num1, num2) {
	let m = 0
	const s1 = num1.toString()
	const s2 = num2.toString()
	try {
		m += (s1.split('.')[1] || []).length
	} catch (e) {
		console.log(e)
	}
	try {
		m += (s2.split('.')[1] || []).length
	} catch (e) {
		console.log(e)
	}
	return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
}

/**
 * 两个浮点数相除
 * @author yxk
 * @param num1
 * @param num2
 * @return {number}
 */
export function divideOperation(num1, num2) {
	let m = 0
	const s1 = num1.toString()
	const s2 = num2.toString()
	try {
		m += (s1.split('.')[1] || []).length
	} catch (e) {
		console.log(e)
	}
	try {
		m += (s2.split('.')[1] || []).length
	} catch (e) {
		console.log(e)
	}
	const n1 = multiOperation(num1, Math.pow(10, m))
	const n2 = multiOperation(num2, Math.pow(10, m))
	return Number(n1) / Number(n2)
}

/**
 * 金额转换
 * 1234567.05 =>  1,234,567.05
 * @author yxk
 * @param {string|number} num 金额
 * @param {string} emptyStr 金额错误时，补空位
 * @return {string}
 */
export function splitNumber(num, emptyStr = '--') {
	if (num === 0) return num
	if (!num) return emptyStr
	num = Number(num)
	if (isNaN(num)) return emptyStr
	if (num < 1000) return num.toFixed(2)
	num = num.toFixed(2)

	let numArr = num.split('.')
	let endStr = numArr.length > 1 ? numArr[1] : null

	let arr = numArr[0].split('');
	let arr0 = [].concat(arr);
	let index = 0;
	for (let i = arr0.length - 1; i >= 0; i--) {
		let j = arr.length - i;
		if (i % 3 === 0 && i !== 0) {
			arr0.splice(j + index, 0, ',');
			index++
		}
	}
	let res = arr0.join('')
	return endStr ? `${res}.${endStr}` : res;
}

/**
 * 判断是否为手机号
 * @param {String} val
 */
export function isMobile(val) {
	const reg = /^1\d{10}$/
	return reg.test(val)
}

/**
 * 判断是否为邮箱
 * @param {String} val
 */
export function isEmail(val) {
	const reg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/
	return reg.test(val)
}

/**
 * 判断Appid
 * @param {String} val
 */
export function isAppid(val) {
	const reg = /[a-zA-Z0-9]{8}/
	return reg.test(val)
}

/**
 * rpx 转 px
 * @param {String|Number} val
 */
export function unitToPx(val) {
	val = String(val)
	if (val.endsWith('rpx')) {
		let num = val.replace('rpx', '')
		if (isNaN(Number(num))) return val
		return uni.upx2px(num) + 'px'
	} else {
		return val
	}
}

/**
 * 判断两个对象内容是否相同
 * @author yxk
 * @param {Object} obj_1
 * @param {Object} obj_2
 * @return {Boolean}
 */
export function compareObj(obj_1, obj_2) {
	if (obj_1 === obj_2) return true
	if (!types.isObject(obj_1) || !types.isObject(obj_2)) {
		return obj_1 === obj_2
	}

	let keys_1 = Object.keys(obj_1) || []
	let keys_2 = Object.keys(obj_2) || []
	if (keys_1.length !== keys_2.length) {
		keys_1 = keys_2 = null
		return false
	}

	// key 取交集，如果交集数组的长度和不等于数组的长度说明两个数组的值不相同
	let keys = keys_1.filter(o => keys_2.includes(o))
	if (keys.length !== keys_1.length) {
		keys_1 = keys_2 = keys = null
		return false
	}

	for (let i = 0; i < keys.length; i++) {
		let key = keys[i]
		if (!compareObj(obj_1[key], obj_2[key])) {
			keys_1 = keys_2 = keys = null
			return false
		}
	}

	keys_1 = keys_2 = keys = null
	return true
}

/**
 * 加密
 * @param {string} str
 * @return {string}
 */
export function RSAencrypt(str) {
  const jse = new JsEncrypt()
  jse.setPublicKey(PUBLIC_KEY)
  return jse.encrypt(str)
}
